# todo: load and save

__version__= 0.1
__all__ = ['Delikates']

import pydelicious
from time import sleep


class Delikates(object):
    
    def __init__(self, file='', username='', password=''):
        
        # things that must persist from session to session:
        self.relations = {}
        self.bookmarks = {}
        self.tag_count = {}
        self.username = ''

        self.must_wait = False
        self.waiting = 10
        self.file = file

        if username and password:
            self.DeliciousAPI = pydelicious.apiNew(username, password)
            self.absorb()
            self._prepare()
            self.save()
        else:
            self.load(self.file)

    def absorb(self):
        """
        absorb() 

        Absorb from del.icio.us the tags of given user. The arguments
        are the username and the password.  
        """
        self._get_tags()
        self._get_posts()
    

    def save(self, name=''):
        """ 
        Save all the importnat data to a file. If no file is given, then
        the filename given to __init__ is used.

        """
        if not name:
            name = self.file

        to_dump = self.relations, self.bookmarks, self.tag_count, self.username
        import pickle
        try:
            output = open(name, 'wb')
            pickle.dump(to_dump, output)
            output.close()
        except IOError:
            print "The object is not initialized properly, no sense in saving it. Sorry."

    def load(self, name=''):
        """

        Load from a save-file. If none is given, use the filename
        given to __init__.

        """
        if not name:
            name = self.file

        import pickle
        input = open(name, 'rb')
        (self.relations, self.bookmarks, self.tag_count, self.username) = pickle.load(input)
        input.close()

    def make_pajek_file(self, name):
        """Prepare a pajek .net file from the del.icio.us data."""

        # pajek must have \n\r instead of \n. Grrrrrrrr....


        if not self.relations:
            self._prepare()
        f = open(name, 'w')
        
        print >>f, '*Network %s'%(self.username+'_delicious_tags',), '\r'
        
        tag_vertice = {}
        i = 0
        for tag_name in self.relations:
            i += 1
            tag_vertice[tag_name] = i
            
        print >> f, '*Vertices', i, '\r'

        for tag_name in self.relations:
            print >> f, tag_vertice[tag_name], '"'+unicode(tag_name).encode('cp1250')+'"', '\r'
            
        print >>f, '*Arcs', '\r'

        for tag_name in self.relations:
            big_vertex = tag_vertice[tag_name]
            for little_tag in self.relations[tag_name]:
                # weigth is the number of common posts divided by the total number of posts of the "from" tag
                
                weight = 100*float(self.relations[tag_name][little_tag])/float(self.tag_count[tag_name])
                small_vertex = tag_vertice[little_tag]
                print >> f, '%3d %4d %8d'%(big_vertex, small_vertex, weight), '\r'
        
        
        f.close()


    def _prepare(self):
        self.relations = {}
        for t in self.bookmarks:
            co_tags = {}
            for post in self.bookmarks[t]:
                for tag in post:
                    if t.lower() != tag.lower():
                        try:
                            co_tags[tag.lower()] += 1
                        except KeyError:
                            co_tags[tag.lower()] = 1
            self.relations[t] = co_tags
    

    def _get_posts(self):

        self._wait()

        print 'Getting posts...'
        posts = self.DeliciousAPI.posts_all()
        for p in posts:
            try:
                for t in p['tags'].split(' '):
                    self.bookmarks[t.lower()].append(p['tags'].split(' '))
            except KeyError:
                print p

                    
        print "Got %s posts."%(len(posts))


    def _get_tags(self):

        self._wait()

        self.must_wait = True
        print "Getting tags..."
        self.bookmarks = {}
        self.tag_count = {}
        raw_tags = self.DeliciousAPI.tags_get()
        for t in raw_tags:
            name = t['tag'].lower()
            count = int(t['count'])
            self.bookmarks[name] = []
            self.tag_count[name] = count
            print "Got", name

        print "Got tags."

    def _wait(self):
        if self.must_wait:
           print "Waiting %s seconds..."%(self.waiting,)
           sleep(self.waiting) 
        self.must_wait = True

class PajekNet(object):
    
    def __init__(self):
        self.arcs_from = {}
        self.arcs_to = {}
        self.edges_to = {}
        self.edges_from = {}

    def vertices(self):
        pass

    def arcs(self):
        pass
    
    def generate(self):
        pass
            




    


